<template>
  <div class="detail">
    <!-- top -->
    <TopView name="detail" :title="queryBlog.title" msg=""></TopView>

    <div class="icons">
      <div class="flag">{{ queryBlog.flag }}</div>
      <div class="author">
        <i class="el-icon-user" style="margin-right: 5px"></i>
        <span>{{ queryBlog.nickname }}</span>
      </div>
      <div class="time">
        <i class="el-icon-date" style="margin-right: 5px"></i>
        <span>{{ queryBlog.createTime }}</span>
      </div>
      <div class="type">
        <i class="el-icon-copy-document" style="margin-right: 5px"></i>
        <span>{{ queryBlog.typeName }}</span>
      </div>
      <div class="views">
        <i class="el-icon-view" style="margin-right: 5px"></i>
        <span>{{ queryBlog.views }}</span>
      </div>
      <div class="comment">
        <i class="el-icon-chat-line-round" style="margin-right: 5px"></i>
        <span>{{ commentList.length }}</span>
      </div>
    </div>

    <div class="detail-wrap">
      <div class="content-wrap">
        <div class="left">
          <!-- 文章内容 -->
          <div class="detail_con" :style="loading ? 'height:200px;' : 'height:auto;'" v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
            <div v-highlight ref="blogContentRef" @click="clickImage" v-html="blogInfo.content"></div>
          </div>

          <!-- 评论列表 -->
          <h2 style="padding: 20px 0; box-sizing: border-box; border-top: 2px solid #0bbd87">
            <div style="text-align: center; margin-bottom: 20px">
              <el-button type="primary" @click="publish()">评论</el-button>
            </div>
            全部评论
            <span style="margin-left: 10px; color: #f2711c; font-weight: bold">{{ commentList.length }}</span>
          </h2>

          <!-- 父级评论 -->
          <div class="list" v-for="item in commentList" :key="item.id">
            <el-image :src="item.avatar" lazy fit="cover" />
            <div class="detail">
              <div class="top">
                <span class="name">{{ item.nickname }}</span>
                <span class="time">{{ item.createTime }}</span>
              </div>
              <div class="bottom">{{ item.content }}</div>
              <el-button type="text" size="small" @click="reply(item)">回复</el-button>

              <!-- 子级评论 -->
              <template v-if="item.replyComments.length > 0">
                <div style="background-color: #f0f8ff" class="list" v-for="sub_item in item.replyComments" :key="sub_item.id">
                  <el-image :src="sub_item.avatar" lazy fit="cover" />
                  <div class="detail">
                    <div class="top">
                      <span class="name">{{ sub_item.nickname }}</span>
                      <span class="time">{{ sub_item.createTime }}</span>
                    </div>
                    <div class="bottom">{{ sub_item.content }}</div>
                  </div>
                </div>
              </template>
            </div>
          </div>
        </div>

        <div class="right">
          <div class="wather">
            <h2>天气</h2>
            <div class="con-wrap">
              <div class="left-wrap">
                <el-image :src="require('../assets/wather/sun.png')" lazy fit="cover"></el-image>
              </div>
              <div class="right-wrap">
                <div class="img-wrap">
                  <el-image :src="require('../assets/wather/hot.png')" lazy fit="cover"></el-image>
                  <el-image :src="require('../assets/wather/cold.png')" lazy fit="cover"></el-image>
                </div>
                <div class="temperature">
                  <div class="high">最高温：32°</div>
                  <div class="low">最低温：25°</div>
                </div>
              </div>
            </div>
          </div>
          <div class="directory">
            <h2>目录</h2>
            <ul>
              <template v-for="(item, index) in catalog">
                <!---根据read属性，动态绑定样式：为true即为正在阅读此内容--->
                <li :key="index" :style="{ paddingLeft: item.level * 30 - 44 + 'px' }" :class="{ ll: item.read == true }">
                  <!---设置href，用于目录的跳转；动态绑定id，判断当前正在阅读的是哪一个小标题的内容--->
                  <a :id="item.id" @click="goAnchor(index, '#' + item.id)" :class="{ cc: item.read == true }" v-html="item.title"></a>
                </li>
              </template>
            </ul>
          </div>
        </div>
      </div>
    </div>

    <!-- 图片放大预览 -->
    <el-image ref="previewImageRef" style="display: none" :src="previewUrl" :preview-src-list="urls"></el-image>

    <!-- 弹框 -->
    <el-dialog :title="dialogTitle" :visible.sync="showDialog" :close-on-click-modal="false" @close="closeDialog('form')" @close-on-press-escape="closeDialog('form')">
      <el-form ref="form" :model="form" label-width="100px" :rules="rules">
        <el-form-item label="昵称" prop="nickname">
          <el-input v-model="form.nickname" placeholder="请输入昵称" />
        </el-form-item>
        <el-form-item label="回复" prop="content">
          <el-input style="height: 150px" type="textarea" v-model="form.content" placeholder="请输入回复" />
        </el-form-item>
        <el-form-item label="头像地址" prop="avatar">
          <el-input placeholder="请输入头像地址" v-model="form.avatar"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input placeholder="请输入邮箱" v-model="form.email"></el-input>
        </el-form-item>
      </el-form>
      <div style="text-align: right">
        <el-button type="danger" @click="closeDialog('form')">取消</el-button>
        <el-button type="primary" @click="confirm('form')">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import commentApi from '@/api/comment.js'
import homeApi from '@/api/home.js'
import TopView from '@/components/TopView.vue'
export default {
  name: 'MessageView',
  components: {
    TopView
  },
  data() {
    return {
      loading: true,
      queryBlog: {},
      blogInfo: {},
      showDialog: false,
      dialogTitle: '',
      commentList: [],
      previewUrl: '',
      urls: [],
      catalog: [],
      form: {
        nickname: '',
        email: '',
        content: '',
        avatar: 'https://test-1256689020.cos.ap-nanjing.myqcloud.com/images/qq5.jpg',
        parentCommentId: '-1',
        adminComment: true
      },
      rules: {
        nickname: [{ required: true, message: '昵称不能为空', trigger: 'blur' }],
        content: [{ required: true, message: '评论不能为空', trigger: 'blur' }],
        avatar: [{ required: true, message: '头像地址不能为空', trigger: 'blur' }]
      }
    }
  },
  created() {
    this.queryBlog = this.$route.query
    this.getBlogDetail()
    this.getCommentList()
  },
  methods: {
    // 获取文章详情
    getBlogDetail() {
      homeApi.getBlog({ id: this.queryBlog.id }).then(res => {
        this.blogInfo = res.data.data
        this.getTitle()
      })
    },

    // 获取博客文章目录及给代码块添加复制按钮
    getTitle() {
      // 生成目录
      this.$nextTick(() => {
        // 根据ref来获取文章的内容
        const articleContent = this.$refs.blogContentRef
        // 想获取的标题，将想获取的标题的标签添加到这
        const titleTag = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']
        // 存放标题的数组
        const titles = []
        // 遍历文章内容节点
        articleContent.childNodes.forEach((e, index) => {
          // 找出需要做成目录的标题并在内容中给这些标题添加id属性(可用于锚点跳转)
          if (titleTag.includes(e.nodeName)) {
            // 具体封装过程
            const id = 'header-' + index
            // 设置元素id
            e.setAttribute('id', id)
            // 最终目录
            titles.push({
              id: id,
              title: e.innerHTML,
              level: Number(e.nodeName.substring(1, 2)),
              nodeName: e.nodeName,
              // read：后期主要用来判断当前阅读的是哪一个小标题的内容
              read: false
            })
          }

          // 每个代码块添加复制按钮
          if (e.nodeName === 'PRE') {
            const copyButton = document.createElement('button')
            copyButton.setAttribute('class', 'btn-pre-copy')
            copyButton.innerHTML = '复制'
            copyButton.onclick = () => {
              const copyData = e.firstChild.innerText
              this.copyToClipboard(copyData)
              copyButton.innerHTML = '复制成功'
              setTimeout(() => {
                copyButton.innerHTML = '复制'
              }, 1000)
            }
            e.appendChild(copyButton)
          }
        })

        // 最终目录赋值给catalog
        this.catalog = titles
        // loading
        this.loading = false
      })
    },

    // js复制到剪贴板
    copyToClipboard(content) {
      if (window.clipboardData) {
        window.clipboardData.setData('text', content)
      } else {
        ;(content => {
          document.oncopy = e => {
            e.clipboardData.setData('text', content)
            e.preventDefault()
            document.oncopy = null
          }
        })(content)
        document.execCommand('Copy')
      }
    },

    // 目录锚点跳转
    goAnchor(index, id) {
      // 被点击的目录对应内容中的标题样式改变
      for (let i = 0; i < this.catalog.length; i++) {
        if (index === i) {
          this.catalog[i].read = true
          document.getElementById(this.catalog[i].id).style.color = '#0eba8a'
        } else {
          this.catalog[i].read = false
          document.getElementById(this.catalog[i].id).style.color = '#666'
        }
      }

      // 参数是id选择器
      document.querySelector(id).scrollIntoView({
        behavior: 'smooth', // 动画过渡效果-behavior: "auto" 或 "smooth" 默认为 "auto"
        block: 'center', // 垂直方向对齐-block: "start", "center", "end", 或 "nearest" 默认为 "start"
        inline: 'center' // 水平方向对齐-inline: "start", "center", "end", 或 "nearest" 默认为 "nearest"
      })
    },

    // 点击文章图片进行放大预览
    clickImage(e) {
      if (e.target.tagName.toUpperCase() === 'IMG') {
        // 当前点击的img地址
        this.previewUrl = e.target.currentSrc
        // 定义一个数组用来接收img地址
        this.urls.push(e.target.currentSrc)
        // 图片预览
        this.$refs.previewImageRef.clickHandler()
      }
    },

    // 获取评论列表
    getCommentList() {
      commentApi.listComment({ blogId: this.queryBlog.id }).then(response => {
        if (response.code === 20000) {
          this.commentList = response.data.data
        } else {
          this.$message.error(response.message)
        }
      })
    },

    // 发布
    publish() {
      this.dialogTitle = '评论'
      this.showDialog = true
    },

    // 回复
    reply(comment) {
      this.form.parentCommentId = comment.id
      this.dialogTitle = '回复' + comment.nickname + '的评论'
      this.showDialog = true
    },

    // 确认评论按钮
    confirm(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          const form = new FormData()
          form.append('nickname', this.form.nickname)
          form.append('email', this.form.email)
          form.append('content', this.form.content)
          form.append('parentCommentId', this.form.parentCommentId)
          form.append('avatar', this.form.avatar)
          form.append('blogId', this.queryBlog.id)
          form.append('adminComment', this.form.adminComment)

          commentApi.saveComment(form).then(response => {
            if (response.code === 20000) {
              this.$message.success(response.message)
              // 清除缓存
              this.closeDialog('form')
              // 刷新页面
              this.getCommentList()
            } else {
              this.$message.error(response.message)
            }
          })
        }
      })
    },

    // 关弹框
    closeDialog(formName) {
      this.$refs[formName].resetFields()
      this.form = {
        nickname: '',
        email: '',
        content: '',
        avatar: 'https://test-1256689020.cos.ap-nanjing.myqcloud.com/images/qq5.jpg',
        parentCommentId: '-1',
        adminComment: true
      }
      this.showDialog = false
    }
  }
}
</script>

<style lang="less" scoped>
.detail {
  width: 100%;
  height: auto;

  .icons {
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
    align-items: center;
    position: relative;
    top: -170px;
    left: 0;
    color: #fff;
    font-size: 16px;
    font-weight: bold;

    .flag,
    .author,
    .time,
    .type,
    .views {
      margin-right: 20px;
    }

    .flag {
      background-color: orangered;
      padding: 3px;
      box-sizing: border-box;
      border-radius: 2px;
    }
  }

  .detail-wrap {
    width: 100%;
    height: auto;
    padding: 0 10%;
    box-sizing: border-box;
    opacity: 0.95;
    position: relative;
    top: -60px;
    left: 0;

    .content-wrap {
      width: 90%;
      height: auto;
      margin: 0 auto 30px auto;
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      align-items: flex-start;

      .left {
        width: calc(100% - 320px);
        height: auto;
        padding: 30px;
        box-sizing: border-box;
        border-radius: 5px;
        border: 1px solid #eaeefb;
        background-color: #fff;
        box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
        text-align: left;

        .detail_con {
          width: 100%;
          background-color: #e6ffff;
          padding: 10px 20px;
          box-sizing: border-box;
          margin-bottom: 20px;

          // 标题
          /deep/ h1,
          /deep/ h2,
          /deep/ h3,
          /deep/ h4,
          /deep/ h5,
          /deep/ h6 {
            padding: 10px 0;
          }

          // 代码块
          /deep/ pre {
            font-family: Consolas;
            text-align: left;
            padding: 1em;
            padding-left: 3.5em; // 0.8em
            border-radius: 5px;
            counter-reset: line;
            white-space: pre;
            word-spacing: normal;
            word-break: normal;
            word-wrap: normal;
            line-height: 1.5;
            overflow: auto;
            position: relative;

            &:hover .btn-pre-copy {
              display: block;
            }

            .btn-pre-copy {
              position: absolute;
              top: 10px;
              right: 10px;
              font-size: 12px;
              line-height: 1;
              cursor: pointer;
              color: #3a3a3a;
              padding: 5px 8px;
              box-sizing: border-box;
              background-color: #ffffff;
              border: 0;
              border-radius: 2px;
              display: none;
            }

            // .hljs-ln-n {
            //   padding-right: 10px;
            //   margin-right: 10px;
            //   box-sizing: border-box;
            //   border-right: 1px solid #0eba8a;
            // }
          }

          // 有序列表，无序列表
          /deep/ ol,
          /deep/ ul {
            padding: 10px 28px;
            background-color: #fffaec;
            border-radius: 6px;
            margin-bottom: 10px;
            color: #2e2e2e;

            li {
              line-height: 30px;
            }
          }

          // 段落
          /deep/ p {
            line-height: 30px;
          }

          // 图片
          /deep/ img {
            width: 50%;
            height: 100%;
            max-width: 100%;
            border-radius: 6px;
            object-fit: contain;
            margin: 10px auto;
            display: block;
            box-shadow: 0 0 16px hsl(0deg 0% 43% / 45%);
            cursor: zoom-in !important;
          }

          /deep/ .el-textarea__inner {
            height: 100%;
          }

          /deep/ .ql-align-center {
            display: flex;
            justify-content: center;
            flex-flow: row nowrap;
            align-items: center;
          }
        }

        .list {
          width: 100%;
          padding: 10px;
          box-sizing: border-box;
          border-radius: 5px;
          height: auto;
          display: flex;
          justify-content: flex-start;
          flex-flow: row nowrap;
          margin-bottom: 10px;

          .el-image {
            height: 40px;
            width: 40px;
            border-radius: 50%;
            vertical-align: middle;
            max-width: 100%;
          }

          .detail {
            width: 100%;
            padding: 0 10px;
            box-sizing: border-box;

            .top {
              margin-bottom: 10px;
              .name {
                font-weight: bold;
                margin-right: 10px;
              }
              .time {
                font-size: 12px;
              }
            }
          }
        }
      }

      .right {
        width: 300px;
        height: auto;
        margin-left: 20px;
        position: sticky;
        top: 70px;
        transition: top 0.2s;

        .wather {
          width: 100%;
          height: 200px;
          background-color: #fff;
          border-radius: 5px;
          padding: 20px;
          box-sizing: border-box;
          margin-bottom: 20px;

          h2 {
            line-height: 40px;
            border-bottom: 1px solid rgb(11, 189, 135);
            margin-bottom: 20px;
          }

          .con-wrap {
            width: 100%;
            height: 99px;
            display: flex;
            flex-flow: row nowrap;
            justify-content: center;
            align-content: center;

            .left-wrap {
              width: 80px;
              height: 100%;
              margin-right: 10px;
              display: flex;
              align-items: center;

              @keyframes beat {
                to {
                  transform: scale(1.2);
                }
              }

              .el-image {
                width: 100%;
                height: 80px;
                animation: beat 0.35s infinite alternate;
              }
            }

            .right-wrap {
              width: calc(100% - 90px);
              height: 100%;

              .img-wrap {
                width: 100%;
                height: 60px;
                margin-bottom: 10px;
                display: flex;
                flex-flow: row nowrap;
                justify-content: space-around;
                align-content: center;
                .el-image {
                  width: 60px;
                  height: 60px;
                }
              }

              .temperature {
                width: 100%;
                display: flex;
                flex-flow: row nowrap;
                justify-content: center;
                align-content: center;
                .high,
                .low {
                  font-size: 12px;
                  text-align: center;
                  width: 50%;
                }
              }
            }
          }
        }

        .directory {
          width: 100%;
          height: auto;
          background-color: #fff;
          border-radius: 5px;
          padding: 20px;
          box-sizing: border-box;
          text-align: left;

          h2 {
            line-height: 40px;
            border-bottom: 1px solid rgb(11, 189, 135);
            margin-bottom: 20px;
          }

          ul {
            .ll {
              border-left: solid 4px #0eba8a;
            }

            li {
              padding: 0 10px;
              box-sizing: border-box;
              font-weight: bold;
              font-size: 20px;
              margin-bottom: 15px;
              list-style: none;
              line-height: 25px;
              border-left: solid 4px #ffffff;

              &:hover {
                background-color: #e6ffff;
              }

              &:last-child {
                margin-bottom: 0;
              }

              .cc {
                color: #13bc8a;
              }

              a {
                color: #666;
                font-size: 15px;
                display: block;
                width: 100%;
                cursor: pointer;
              }
            }
          }
        }
      }
    }
  }
}
</style>
